package cn.wolfcode.controller;


import cn.wolfcode.domain.User;
import cn.wolfcode.domain.vo.UserVo;
import cn.wolfcode.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import reactor.core.publisher.Mono;

@Controller //  Spring 注解：将当前类创建对象并纳入到 Spring 容器中。
@RequestMapping("/api/auth")   // /api/auth/login  二级路径。将来访问  二级路径 + 一级路径访问。防止一级路径重复问题
public class UserController {

    // 由于我们请求是 Post 请求。所以需要使用 PostMapping
    // 由于我们是异步请求，我们使用 Mono<ResponseEntity<UserVo>> 他能更好的处理异步请求，给我们响应流式数据。
    // Mono : 代表单个，含义是：只包含一个或没有。
        // 有一个代表存了需要向前端返回的数据
        // 没有代表登录失败了
    // Mono<ResponseEntity<UserVo>>   Response --> 响应的意识  Entity --> 实体  UserVo --> 我们子集定义的需要返回的类型
    // 放到一起就是 需要响应的一个实体，类型是 UserVo
    // 总结：需要返回一个实体Vo对象。若存在则封装到 Mono 中，不存在则代表失败。
    // 后台想要接收 JSON 格式字符串类型的参数，就必须使用要给注解 @RequestBody

    @Autowired  // 从 Spring 容器中获取 IUserService 类型的 userService 对象。 多态。 接口类型 --> 实现类对象。
    private IUserService userService;

    @PostMapping("/login")
    public Mono<ResponseEntity<UserVo>> login(@RequestBody User user){
        // 调用 IUserService 接口的实现类来处理这个登录请求，最终返回给我们一个 Mono<UserVo> 对象
        Mono<UserVo> userMono = userService.login(user);
        // 封装一个 Mono<ResponseEntity<UserVo>> 对象中的属性。让其判定里面是否存在数据。
        // userMono.map(ResponseEntity::ok) 调用 userMono.map() 方法。 该方法需要我们传递一个 Stream 方式。
        // ResponseEntity::ok  调用 ResponseEntity 类中的 OK 方法。  状态成功 状态码 200
        Mono<ResponseEntity<UserVo>> responseMono =
                userMono.map(ResponseEntity::ok)        // 成功  状态码 200
                        // defaultIfEmpty(ResponseEntity.status(401).build());
                        // Mono 对象中若为 Null 则构建一个状态码为 401 并返回。
                        .defaultIfEmpty(ResponseEntity.status(401).build());   // 失败
            // 若存在数据返回一个 OK  登录成功
            // 若不存在数据则封装一个状态  401  没有权限  登录失败

        // 最终将数据返回

        return responseMono;
    }

}
